package main

import (
	"log"
)

// ConnLimiter 定义 连接信息
type ConnLimiter struct {
	concurrentConn int      // 连接个数
	buket          chan int // 管道
}

// 缓冲的 chan， make(chan int, 缓冲大小)，表示满了 缓冲大小后 就开始堵塞，无法在往 管道 塞入数据
// 不带缓冲区 chan，make(chan int) , 就是放入数据之后，没有取出这个数据就无法在继续放入数据
// NewConnLimiter 创建 ConnLimiter
func NewConnLimiter(cc int) *ConnLimiter {
	return &ConnLimiter{
		concurrentConn: cc,
		buket:          make(chan int, cc), // 缓冲的 chan， make(chan int, 缓冲大小)，表示满了 缓冲大小后 就开始堵塞，无法在往 管道 塞入数据
	}
}

// 判断是否是否可以获取连接
// GetConn 获取请求的 buket token 连接
func (cl *ConnLimiter) GetConn() bool {

	// cap(ch1) 可以查看缓冲区长度
	// len(ch1) 可以查看缓冲区有多少未读的缓存数据
	if len(cl.buket) >= cl.concurrentConn {
		log.Printf("没有多的 bucket token.")
		return false
	}

	cl.buket <- 1
	return true
}

// ReleaseConn 释放连接
func (cl *ConnLimiter) ReleaseConn() {
	c := <-cl.buket
	log.Printf("释放  bucket token. %v", c)
}
